// #include "server.hpp"

// int main()
// {
//     Socket server;
//     if (server.CreateServer(8080) == false)
//     {
//         ERR_LOG("create error");
//         return 0;
//     }
//     int sockfd = server.Accept();
//     Socket link(sockfd);
//     char buffer[1024];

//     while (1)
//     {
//         int ret = link.Read(buffer, sizeof(buffer) - 1);
//         if (ret > 0)
//         {
//             buffer[ret] = 0;

//             DBG_LOG("recv %s", buffer);

//             link.Send(buffer, ret);
//         }
//         sleep(1);
//     }

//     return 0;
// }

// // #include "server.hpp"

// void Acceptor()
// {
// }

// int main(int argc, char* args[])
// {
//     Socket server;
//     server.CreateServer(8080);

//     int &&b = int(1);
//     b = 10;
//     std::cout << b << std::endl;
//     // Poller poll;
//     // while (1)
//     // {
//     //     int sockfd = server.Accept();
//     //     Channel

//     // }

//     return 0;
// }

// class Base
// {
// public:
//     Base()
//     {
//         foo(); // 调用纯虚函数 - 危险!
//     }

//     virtual void foo() = 0; // 纯虚函数
// };

// class Derived : public Base
// {
// public:
//     void func() { std::cout << "Derived"; }
//     virtual void foo() // 纯虚函数
//     {}

// };

// int main()
// {
//     Derived d;
//     return 0;
// }

// #include "server.hpp"
// #include <iostream>
// #include <functional>


// void CloseCallback(Channel *channel)
// {
//     channel->Remove();     //这个是将文件描述符从epoll模型中移除， 并且将文件描述符关闭。 
//     delete channel;        //这个是删除管理文件描述符的这个channel。 可以直接删除， 因为channel里面没有必须是释放的管理的资源。
// }
// void ReadCallback(Channel *channel)
// {
//     int fd = channel->Fd();
//     char buffer[1024];
//     int n = recv(fd, buffer, sizeof(buffer), 0);
//     if (n < 0)
//     {
//         CloseCallback(channel);        //并且如果接收失败了， 说明有错误发生， 还要将文件描述符关了
//         DBG_LOG("读失败了， 打开写事件");
//     }
//     buffer[n] = 0;
//     DBG_LOG("recv fd kernel buffer: %s", buffer);
//     channel->EnableWrite();
// }

// void WriteCallback(Channel *channel)
// {
//     int fd = channel->Fd();
//     std::string buffer = "nihao";
//     int n = send(fd, buffer.c_str(), buffer.size(), 0);
//     if (n < 0)
//     {
//         CloseCallback(channel);            //如果向Kernel buffer中写数据出错了， 也要在epoll中直接删掉文件描述符， 然后close。
//     }

//     channel->DisableWrite();
// }
// void ErrorCallback(Channel *channel)
// {
//     //错误了， 就直接关闭除掉channel中的数据和文件描述符就行了。 
//     ERR_LOG("error, excute ErrorCallback");
//     CloseCallback(channel);
// }
// void EventCallback(Channel *channel)
// {
//     DBG_LOG("EventCallback()");
// }

// // void Acceptor(Channel *lst_channel, EventLoop *poller)    /*这里有参数，设置给lst_channel则为无参数， 使用bind设置进去*/
// // {
// //     int fd = lst_channel->Fd();
// //     int newfd = accept(fd, nullptr, nullptr);  //接收不需要获取对方的地址信息
// //     Channel *newChannel = new Channel(newfd, poller);
// //     // DBG_LOG("成功创建一个新连接");
// //     // sleep(11111);
// //     newChannel->SetReadCallback(std::bind(ReadCallback, newChannel));
// //     newChannel->SetWriteCallback(std::bind(WriteCallback, newChannel));     
// //     newChannel->SetErrorCallback(std::bind(ErrorCallback, newChannel));     
// //     newChannel->SetCloseCallback(std::bind(CloseCallback, newChannel));     
// //     newChannel->SetEventCallback(std::bind(EventCallback, newChannel));     

// //     newChannel->EnableRead();
// // }

// int main()
// {
//     //目前为单Reactor单线程。 逻辑：创建监听服务。 然后利用监听服务的fd创建监听lst_channel。 
//     //2、创建poller，这个poller目前充当Reactor的工作。 用来执行所有工作， 目前工作只有lst_channel的接收新连接、读写IO。
//     //   并且这些工作都是通过事件监控处理的。
//     //大逻辑就是一个新连接到来， listfd就绪，创建新连接。 然后假如epoll模型。 然后写到来了， 时间就徐，新连接读事件读到数据。 打开写事件， 就绪
//     //写入数据。
//     Socket lst_sock;
//     lst_sock.CreateServer(8080);
//     EventLoop baseloop;

//     Channel lst_channel(lst_sock.Fd(), &baseloop);
//     lst_channel.SetReadCallback(std::bind(Acceptor, &lst_channel, &baseloop));
//     lst_channel.EnableRead();

//     baseloop.Start();
// }




// #include <iostream>
// using namespace std;
// #include <algorithm>

// int main()
// {
//     int a, b, c;
//     cin >> a >> b >> c;

//     if (a < b && a < c) cout << b << " " << a << " " << c << endl;
//     else if (b < a && b < c) cout << a << " " << b << " " << c << endl;
//     else if (c < a && c < b) cout << a << " " << c << " " << b << endl;
//     else cout << -1 << endl;
//     return 0;
// }

// 1
// 5 4 3
// 60 50 50 40
// 40 50 50 60
// 100 80 90 20 40
// 40 60 80 -1 80
// -1 30 80 -1 90
// 30 100 20 10 100
// 3600 2400 1800 200 5000
// 20 30 35 0 40


// #include <iostream>
// #include <unordered_map>
// #include <unordered_set>
// using namespace std;

// int main()
// {
//     int t = 0;
//     cin >> t;

//     while (t--)
//     {
//         int n;
//         cin >> n;
//         unordered_map<int, int> mp;
//         unordered_set<int> st;
//         for (int i = 1; i <= n; i++)
//         {
//             int tmp;
//             cin >> tmp;
//             mp[tmp]++;
//             st.insert(i);
//         }  
//         for (auto &[x, y] : mp)
//         {
//             st.erase(x);
//         }
//         if (st.size() > 0)
//         {
//             cout << *st.begin() << endl;
//         }
//         cout << -1 << endl;
//     }


//     return 0;
// }

// #include <iostream>
// using namespace std;
// #include <string>


// int main()
// {
//     int t = 0;
//     cin >> t;
//     while (t--)
//     {
//         string str;    //最多可以处理10 * 10 * 10的位数, 不够20000， 说明只能记忆化了。先不已计划， 试一下， 
//         cin >> str;
//         if (str.size() == 1) 
//         {
//             cout << str << endl;
//             continue;
//         }

//         int left = 1;

//         while (left < str.size())
//         {
//             if ((str[left] - '0') > (str[left - 1] - '0'))
//             {
//                 char tmp = str[left];
//                 str[left] = str[left - 1];
//                 str[left - 1] = tmp;
//                 cout << str << endl;
//                 break;
//             }
//             left++;
//         }

//     }


//     return 0;
// }


// #include <iostream>
// using namespace std;
// #include <unordered_map>
// #include <unordered_set>
// #include <map>
// #include <set>
// #include <vector>

// struct MyHash
// {
//     size_t operator()(const pair<int, int> &p1) const 
//     {
//         size_t hashi = 1;
//         hashi += p1.first;
//         hashi *= 13;
//         hashi += p1.second;
//         return hashi;
//     }
// };

// bool operator==(const pair<int, int> &p1, const pair<int, int> &p2)    //pair是我们要存储的下标
// {
//     return p1.first == p2.first && p1.second == p2.second;
// }

// int main()
// {
//     int t = 0;
//     cin >> t;
//     while (t--)
//     {
//         int n;
//         cin >> n;
//         unordered_map<int, vector<int>> a;    //记录相同的横坐标
//         unordered_map<int, vector<int>> b;    //记录相同的纵坐标
//         unordered_map<int, unordered_set<int>> hash1;
//         unordered_set<pair<int, int>, MyHash> st;
//         int sum = 0;
//         for (int i = 1; i <= n; i++)
//         {
//             int tmp;
//             cin >> tmp;                //获取下表
//             a[tmp].push_back(i);       //将第i个塔放到对应下表的桶中
//         }

//         for (auto &[index, vec] : a)    //拿到a里面的桶
//         {
//             int k = vec.size();   //有几个元素
//             if (k == 1) continue;

//             int tmp = k - 1;
//             sum += ((1 + tmp) * tmp ) / 2;   //这么说此时将1和4都存入了{1, {1, 4}}中
//         }

//         for (int i = 1; i <= n; i++)
//         {
//             int tmp;
//             cin >> tmp;    //获取下表
//             b[tmp].push_back(i);       //将第i个塔放到对应下表的桶中
//         }

//         for (auto &[index, vec] : b)    //拿到a里面的桶
//         {
//             int k = vec.size();
//             if (k == 1) continue;
//             int tmp = k - 1;
//             sum += (1 + tmp) * tmp / 2;
//         }

//         cout << sum << endl;
//     }

//     return 0;

// }

// // 2
// // 4
// // 1 2 3 1
// // 2 3 1 3



// #include <iostream>
// using namespace std;
// #include <unordered_map> 
// #include <queue>
// #include <vector>


// int main()
// {
//     int n, q;
//     cin >> n >> q;
//     unordered_map<int, vector<int>> path;
//     for (int i =0; i < n; i++)
//     {
//         int tmp1 = 0;
//         int tmp2 = 0;
//         cin >> tmp1 >> tmp2;
//         path[tmp1].push_back(tmp2);
//         path[tmp2].push_back(tmp1);
//     }
//     //

//     while (q--)
//     {
//         int k, s, x;
//         cin >> s >> x >> k;   //从s出发到x
//         if (path[x].size() == 0) 
//         {
//             cout << "No" << endl;
//             continue;
//         }
//         int count = k;
//         queue<int> q;
//         q.push(s);
//         int flag = 0;
//         while (q.size() && count >= 0)
//         {
//             int size = q.size();
//             while (size--)
//             {
//                 int next = q.front();
//                 q.pop();
//                 if (count == 0 && next == x)
//                 {
//                     flag = 1;
//                     break;
//                 }
//                 for (auto &e : path[next])    //将道路的下一个走到的节点取出来， 等待下一次走。
//                 {
//                     q.push(e);
//                 }
//             }
//             count--;
//             if (flag == 1)
//             {
//                 break;
//             }
//         }

//         if (flag == 1)
//         {
//             cout << "Yes" << endl;
//         }
//         else 
//         {
//             cout << "No" << endl;
//         }

//     }

//     return 0;
// }

// 5 1
// 1 2
// 1 3
// 2 3
// 3 4
// 4 5
// 1 5 3



// int main()
// {
//     Socket socket;
//     socket.CreateServer(8080);
//     int newsockfd = socket.Accept();
//     Socket newsocket(newsockfd);
//     while (1)
//     {
//         char buffer[1024];
//         int n = newsocket.Read(buffer, sizeof(buffer));
//         if (n < 0)
//         {
//             cout << 1 << endl;
//         }
//         else if (n == 0)
//         {
//             cout << 0 << endl;
//         }
//         buffer[n] = 0;
//         cout << buffer << endl;
        
//     }
//     return 0;
// }





#include<iostream>
#include "server.hpp"
using namespace std;

using _message_callback = std::function<void(const PtrConn &, Buffer *)>; 
void MessageCallBack(const PtrConn &pcn, Buffer *buf)
{
    DBG_LOG("%s", buf->ReadPosition());
    buf->ReaderMove(buf->ReadAbleSize());

    std::string str = "hello world";
    pcn->Send((char *)str.c_str(), str.size());
}






class EchoServer
{
private:
    TcpServer _server;

public:
    EchoServer(int port = 8080)
        : _server(port)
    {
    }
    void MessageCallBack(const PtrConn &pcn, Buffer *buf)
    {
        DBG_LOG("%s", buf->ReadPosition());
        buf->ReaderMove(buf->ReadAbleSize());

        std::string str = "hello world";
        pcn->Send((char *)str.c_str(), str.size());
    }

    void ServerCloseCallBack(const PtrConn &pcn)
    {
        DBG_LOG("cloase a connection");
    }

    void ConnectedCallBack(const PtrConn &pcn)
    {
        DBG_LOG("create a new Connected %p", pcn.get());
    }

    void Start()
    {
        _server.SetThreadPool(1);
        _server.EnableInactiveConnectDestroy(5);
        _server.SetMessageCallBack(std::bind(&EchoServer::MessageCallBack, this, std::placeholders::_1, std::placeholders::_2));
        _server.SetConnectedCallBack(std::bind(&EchoServer::ConnectedCallBack, this, std::placeholders::_1));
        _server.SetCloseCallBack(std::bind(&EchoServer::ServerCloseCallBack, this, std::placeholders::_1));
        _server.Start();
    }
};




int main()
{
    EchoServer es;
    es.Start();
    return 0;
}
